﻿using System.Diagnostics;
using System.Security.Cryptography;
using System.Text;
using Amazon;
using Amazon.Runtime;
using Amazon.S3;
using Amazon.S3.Model;
using Amazon.S3.Transfer;
using Org.BouncyCastle.Crypto;
using Org.BouncyCastle.Crypto.Parameters;
using Org.BouncyCastle.OpenSsl;
using Org.BouncyCastle.Security;

namespace ConsoleApp2
{
    internal class Program
    {
        static async Task Main(string[] args)
        {


            //            var filesToCompress = new List<string>
            //{
            //    @"D:\1.rar",
            //     @"D:\2.rar",
            //};

            var filesToCompress = new List<string>
{
                @"D:\1.rar",
    @"D:\1.png",
     @"D:\2.png",
          @"D:\test.docx",
};
            string outPath = @"D:\output.zip";



            var cts = new CancellationTokenSource();
            var progress = new Progress<CompressionProgress>(p =>
            {
                Console.Clear();
                Console.WriteLine($"当前文件: {p.CurrentFile} ({p.CurrentFileProgress:P1})");
                Console.WriteLine($"总体进度: {p.OverallProgress:P1}");
                Console.WriteLine($"已处理: {(p.ProcessedBytes)} / {(p.TotalBytes)}");
            });

            // 5秒后自动取消（测试用）
            cts.CancelAfter(TimeSpan.FromSeconds(2));

            try
            {
                var processor = new CompressHelper();
                await Task.Run(async () =>
                {

                    processor.StartCompressFilesAsync(outPath, progress);

                    processor.AddFile(@"D:\1.rar");

                    Task.Delay(2000);
                    processor.AddFile(@"D:\2.png");

                    processor.CompleteAdding();


                    await processor.WaitForCompletionAsync();
                    Console.WriteLine("所有文件处理完成");
                    //Task.Delay(1000);
                    //compressHelper.AddFile(@"D:\2.png");

                });

               


                //await CompressHelper.CompressFilesAsync(
                //    outPath,
                //    progress,
                //    cts.Token);

               
            }
            catch (OperationCanceledException)
            {
                Console.WriteLine("操作已取消");
            }


            return;



            var tt = Guid.NewGuid().ToString();

            var t = ASCLL("登录页面");

            {
                string fileName = "xLUrb8BvGoxdwCkS";
                string fileName2 = "1.txt";
                string path = $"/channel/materialfiles/temp/11165/{fileName}?filename={fileName}";
                string url = GeneratePreSignedURL(path);

            }
            await test();

            Console.ReadLine();
        }


        static string GeneratePreSignedURL(string objectKey)
        {



            string distributionDomain = "dlcdnchannel.asus.com"; // CloudFront 分配的域名
            string s3ObjectPath = objectKey; // S3 对象的路径
            string keyPairId = "K2VLPAZFRX5ANI"; // CloudFront Key Pair ID

            string privateKeyString = @"-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCuDF05cy/Y/b5E
tV4ZOfMFkDNi7KeuZ5pssi+3jtnnW8UqoM7vtkxrN9kgftkDFn5LkKaTvwgboR1V
SM1d86FJ56eNtFMeOtsExxtw+zhkAmht8btSK8UBazYyTWasQCBAI+8YY08e6oIU
e9U1+d1lw19YYMpakxRGNCASVAS/yzdvyfGGSHRzTCdFzmkuogi091A8u9r8SawY
tfnfrmEzbfWrWGg7HDidus6WIpzXitfODyjV63IWvXr+sUz2M11xynMRm76KN1oc
gmJD6gkKJ43PpArgz2lg1IHBUAY5kz47/cQKOk2TkcUIMEov31MpAvpUad71I9UD
Lq8UiY3tAgMBAAECggEAC07eV7c2KqEB1bD69iSft4LQ8+JwWpJ8pAdHtmNfoPqD
auubxlNPz7+HKedT7jFt7zbsu7izrCfhogLi5PHJTuXwKvLGW7ZzOHI/RC3uUgEe
C9ai1wnk+NygXtBMlXBtJ/2tsSXypA2UegQ5rBIZ4ly5OyK+wve/X3hPhSFUVamg
uu5khvZUeKW5d9ZDVVk322TxtNQOE0drXGZEkQLSTIsiOUHWvV75VgnEiW/D1jRR
J22JJ8A9QvzmLqzwReoTS6G8R7AC0m6BSOQwrUw57Z5plG1I9v/3g4EeQuEhmY0C
1kxU0FVWv2VKqZncz+9qdXkO7Ph4wytgWvHOJ86a+QKBgQDw+dkC65ISEC+ipFu0
ObKiG4CERueArt3RBP8mmi/S6LvzjbjlsjWLz4Z9CT5gNB8ry63sx2WvCLnNjuYs
pv6rw35m+u3DA9xA+KcHuIHVCc3h93PLn2hmuKHrm15NVguQ7xeFWrK+NGDcMVYz
47w0lVDpInAe3HkX8kteAoa6ewKBgQC45k1P67SdXko0Nq/2CELl5ruhaFD93+jA
Rf+inauRk5jziuvdfKdDh+pVci3eur0dp8tgDXoJkHg+ehEr6/u+7OHgeYC9c8Iq
IXvJFG5h0uCiLKsNk9V75R+aHc3cUeCiZlIoR7/jvTg9rZOZYDRKaaOdKGRsTsS9
aEu+J7rAtwKBgQDSQj5+1MrUJflaYSx+2aUq2vJM+I0AdBOpUEHNDdXSoi10umDt
Uox0HDQNn2YkjPXxwbtVETqA+g0c9aWSqnclqeL9uc6BTTn+Greq/euS1gYlN0N7
FPEER+9IY31p3z0iTevo+JVjbtJg7k934SqTewFpGhpYYyjpowjt0yh5RwKBgH+T
kDabuKR4YZTDQwfsTVRZro7A7lktPGgmJCtsxOuOPpOUAAhzsOk8h2hrftDWYhRr
KT1eLx0YTI83JE/85FepFHURAM43Z/ov3jww17SxjwL29RNKNJvmzLZG6DqjV+5V
0UwvrWwSrBKKiHPkWFAbsaOHMjs04jSaGODcgtPjAoGAM4eBwclmK62P+TDUHGB6
ZZ2ZvVfQEWtgQzLKSgg3SY+AuBXNPaVx840QGk2umZ4VwX9hj8AOD9q+BHbGffAV
rDZ04lfXnudo+kkuRa+iiqzC045dHyORGyUAb1Bj1goKONof2IM0yxoJuj3Yy61G
ma549uI3FV1zDwbPrWu+U5o=
-----END PRIVATE KEY-----
"; // 私钥字符串

            DateTime expiry = DateTime.UtcNow.AddMinutes(60); // 设置预签名 URL 的有效期

            string signedUrl = GenerateSignedUrl(distributionDomain, s3ObjectPath, keyPairId, privateKeyString, expiry);





            return signedUrl;
        }


        static string GenerateSignedUrl(string distributionDomain, string s3ObjectPath, string keyPairId, string privateKeyString, DateTime expiry)
        {
            string policy = BuildPolicy(distributionDomain, s3ObjectPath, expiry);
            string signature = SignPolicy(policy, privateKeyString);

            return $"https://{distributionDomain}{s3ObjectPath}&Expires={ToUnixTime(expiry)}&Signature={signature}&Key-Pair-Id={keyPairId}";
        }

        static string BuildPolicy(string distributionDomain, string s3ObjectPath, DateTime expiry)
        {
            string policy = $@"{{""Statement"":[{{""Resource"":""https://{distributionDomain}{s3ObjectPath}"",""Condition"":{{""DateLessThan"":{{""AWS:EpochTime"":{ToUnixTime(expiry)}}}}}}}]}}";
            return policy;
        }

        static string SignPolicy(string policy, string privateKeyString)
        {
            using (var reader = new System.IO.StringReader(privateKeyString))
            {
                var pemReader = new PemReader(reader);
                var keyObject = pemReader.ReadObject();

                if (keyObject is AsymmetricCipherKeyPair keyPair)
                {
                    var rsaParams = DotNetUtilities.ToRSAParameters((RsaPrivateCrtKeyParameters)keyPair.Private);
                    return GenerateSignature(policy, rsaParams);
                }
                else if (keyObject is RsaPrivateCrtKeyParameters rsaPrivateKey)
                {
                    var rsaParams = DotNetUtilities.ToRSAParameters(rsaPrivateKey);
                    return GenerateSignature(policy, rsaParams);
                }
                else
                {
                    throw new Exception("Unsupported private key format");
                }
            }
        }
        static string GenerateSignature(string policy, RSAParameters rsaParams)
        {
            using (var rsa = new RSACryptoServiceProvider())
            {
                rsa.ImportParameters(rsaParams);
                var signature = rsa.SignData(Encoding.UTF8.GetBytes(policy), CryptoConfig.MapNameToOID("SHA1"));
                return Convert.ToBase64String(signature).Replace('+', '-').Replace('=', '_').Replace('/', '~');
            }
        }

        static long ToUnixTime(DateTime dateTime)
        {
            return ((DateTimeOffset)dateTime).ToUnixTimeSeconds();
        }


        static async Task test()
        {




            string bucketName = "asus-cdn-origin-s3-dlcdnchannel";
            var accessKey = "AKIAQUFLQDRUK4G4R47T";
            var secretKey = "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";
            var regionName = "ap-northeast-1";
            AWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey);
            var region = RegionEndpoint.GetBySystemName(regionName);
            using var s3Client = new AmazonS3Client(awsCredentials, region);






            var fileMover = new S3BucketFileMover(s3Client);

            // 订阅进度事件
            fileMover.ProgressChanged += progress =>
                Console.WriteLine($"当前进度: {progress}%");

            await fileMover.MoveFileAsync(
                bucketName,
               $"dlcdnchannel/channel/materialfiles/temp/11165/tt.jpg",
            $"dlcdnchannel/channel/materialfiles/temp/11165/tt2.jpg");


            Console.WriteLine("处理完了");
        }


        public static string ASCLL(string source)
        {
            source = source.Trim();
            int lName = source.Length;
            if (lName >= 1)
            {
                source = source.Replace("&amp;", "&");
                source = source.Replace("&apos;", "'");
                source = source.Replace("&quot;", "\"");
                source = source.Replace("&gt;", ">");
                source = source.Replace("&lt;", "<");
                int lName2 = source.Length;
                string aa = source.Trim();
                for (int i = 0; i < lName2; i++)
                {
                    string oneName = aa.Substring(i, 1);
                    int ac = Convert.ToInt32(oneName[0]); //轉ACSII碼
                    if ((ac > 47 && ac < 58) || (ac > 64 && ac < 91) || (ac > 96 && ac < 123) || (ac == 95))
                    {
                    }
                    else
                    {
                        if (ac == 32)
                        {
                            source = source.Replace(oneName, "_");
                        }
                        else if (ac == 43)
                        {
                            source = source.Replace(oneName, "Plus");
                        }
                        else
                        {
                            source = source.Replace(oneName, "");
                        }
                    }
                }
                int dd = 0;
                string ss = "";
                int lName3 = source.Length;
                string aa2 = source.Trim();
                for (int j = 0; j < lName3; j++)
                {
                    string oneName2 = aa2.Substring(j, 1);
                    int ac2 = Convert.ToInt32(oneName2[0]); //轉ACSII碼
                    if ((ac2 == 95))
                    {
                        dd++;
                        if (dd > 1)
                        {
                        }
                        else
                        {
                            ss = ss + oneName2;
                        }
                    }
                    else
                    {
                        ss = ss + oneName2;
                        dd = 0;
                    }
                }
                source = ss;
            }

            return source;
        }
    }
}
